import numpy as np

class Option:
    def __init__(self, nAttr):

class Problem:
    def __init__(self, nOptions, nAttr):
        self.nOptions = nOptions
        self.nAttr = nAttr
        self.P = np.zeros(nOptions)
        for i in range(nOptions):
            self.P[i] = 0.4

        self.C = np.eye(nOptions)
        for i in range(nOptions):
            for j in range(nOptions):
                if i!=j:
                    self.C[i,j] = -1.0/float(nOptions-1)

        self.W = np.zeros(nAttr)
        for i in range(nAttr):
            self.W[i] = 1

        self.M = np.zeros([nOptions, nAttr])
        for i in range(nOptions):
            for j in range(nAttr):
                self.M[i,j] = 1

    def propagate(self):
        alpha = 0.8
        self.P = alpha*self.P + np.dot(np.dot(self.C,self.M),self.W)
        
    def printMe(self):
        print "P:"
        print pr.P
        print "C:"
        print pr.C
        print "M:"
        print pr.M
        print "W:"
        print pr.W

    def maxPreference(self):
        m = 0
        for i in range(self.nOptions):
            if self.P[i] > m:
                m = self.P[i]
        return m

    def maxPreferenceIndex(self):
        m = 0
        index = -1
        for i in range(self.nOptions):
            if self.P[i] > m:
                m = self.P[i]
                index = i
        return m, index
        

    def solve(self, threshold, maxSteps):
        steps = 0
        while self.maxPreference() < threshold:
            self.propagate()
            steps = steps + 1
            if steps <= maxSteps:
                break
        return self.maxPreferenceIndex()


# 3 options, 2 attributes
pr = Problem(3, 2)

pr.printMe()
print "-----"

pr.propagate()

print pr.P

print pr.solve(1.0, 5)

